<%@ page import="java.io.File"%>
<%@ page import="java.io.InputStream"%>
<%@ page import="java.io.FileInputStream"%>
<%@ page import="java.io.BufferedInputStream"%>
<%@ page import="java.io.BufferedOutputStream"%>
<%@ page import="org.apache.commons.codec.binary.Base64"%>

<%
  // byte[] bytes = Base64.getDecoder().decode(request.getParameter("p"));  // use jdk 1.8 and faster
  byte[] bytes = new Base64().decodeBase64(request.getParameter("p"));
  String path = new String(bytes, "UTF-8");
  System.out.println("Downloading " + path);
  File file = new File(path);

  String contentType = getServletContext().getMimeType(file.getName());
  if (contentType == null) {
      contentType = "application/octet-stream";
  }

  out.clear();

  final int DEFAULT_BUFFER_SIZE = 2048; // 2KB.

  response.reset();
  response.setBufferSize(DEFAULT_BUFFER_SIZE);
  response.setContentType(contentType + ";charset=utf-8");
  response.setHeader("Content-Length", String.valueOf(file.length()));
  response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); // Note, the file name should be ASCII.

  // Prepare streams.
  BufferedInputStream input = null;
  BufferedOutputStream output = null;

  try {
      // Open streams.
      input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
      output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

      // Write file contents to response.
      byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
      int length;
      while ((length = input.read(buffer)) > 0) {
          output.write(buffer, 0, length);
      }
  } finally {
      // Gently close streams.
      output.close();
      input.close();
  }
%>
